package com.onlinelearn.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onlinelearn.base.exception.OnlineLearnException;
import com.onlinelearn.base.model.RestResponse;
import com.onlinelearn.content.mapper.TeachplanMapper;
import com.onlinelearn.content.model.dto.BindTeachplanMediaDto;
import com.onlinelearn.content.model.dto.SaveTeachplanDto;
import com.onlinelearn.content.mapper.TeachplanMediaMapper;
import com.onlinelearn.content.model.dto.TeachplanDto;
import com.onlinelearn.content.model.po.Teachplan;
import com.onlinelearn.content.model.po.TeachplanMedia;
import com.onlinelearn.content.service.TeachplanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.beans.Transient;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements TeachplanService {
    @Autowired
    TeachplanMapper teachplanMapper;
    @Autowired
    TeachplanMediaMapper teachplanMediaMapper;
    @Override
    public List<TeachplanDto> findTeachplayTree(long courseId) {
        return teachplanMapper.selectTreeNodes(courseId);
    }

    @Transactional
    @Override
    public void saveTeachplan(SaveTeachplanDto teachplanDto) {

        //课程计划id
        Long id = teachplanDto.getId();
        //修改课程计划
        if(id!=null){
            Teachplan teachplan = teachplanMapper.selectById(id);
            BeanUtils.copyProperties(teachplanDto,teachplan);
            teachplanMapper.updateById(teachplan);
        }else{
            //取出同父同级别的课程计划数量
            int count = getTeachplanCount(teachplanDto.getCourseId(), teachplanDto.getParentid());
            Teachplan teachplanNew = new Teachplan();
            //设置排序号
            teachplanNew.setOrderby(count+1);
            BeanUtils.copyProperties(teachplanDto,teachplanNew);
            teachplanMapper.insert(teachplanNew);
        }

    }
    /**
     * @description 获取最新的排序号
     * @param courseId  课程id
     * @param parentId  父课程计划id
     * @return int 最新排序号
     * @author
     * @date 2022/9/9 13:43
     */
    private int getTeachplanCount(long courseId,long parentId){
        LambdaQueryWrapper<Teachplan> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Teachplan::getCourseId,courseId);
        queryWrapper.eq(Teachplan::getParentid,parentId);
        Integer count = teachplanMapper.selectCount(queryWrapper);
        return count;
    }

    @Transient
    @Override
    public void deleteTeachplan(Long teachplanId) {
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);
//        如果是大分类那么就要判断低下没有任何小分类
        if(teachplan.getParentid() == 0){
//            大分类,查询有没有子分类
            LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(StringUtils.isNotEmpty(String.valueOf(teachplanId)),Teachplan::getParentid,teachplanId);
            List<Teachplan> teachplans = teachplanMapper.selectList(lambdaQueryWrapper);
//            如果不为空,并且没有子类,则可以删除
            if(teachplan != null && teachplans.size() == 0){
                int i = teachplanMapper.deleteById(teachplanId);
            }else{
                throw new OnlineLearnException("课程计划信息还有子级信息，无法操作","120409");
            }
        }else{
//            小分类需要删除关联的媒资信息
//            先删小分类
            LambdaQueryWrapper<TeachplanMedia> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(StringUtils.isNotEmpty(String.valueOf(teachplanId)),TeachplanMedia::getTeachplanId,teachplanId);
            int delete = teachplanMediaMapper.delete(lambdaQueryWrapper);
//            再删大分类
            teachplanMapper.deleteById(teachplanId);
        }
    }
    private final String MOVEUP = "moveup";
    @Override
    public void modifyOrder(String move, Long teachplanId) {
        LambdaQueryWrapper<Teachplan> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Teachplan teachplan = teachplanMapper.selectById(teachplanId);

        List<TeachplanDto> teachplayTree = findTeachplayTree(teachplan.getCourseId());
        if(teachplayTree.size() <= 1) return;
        if(teachplan.getParentid() == 0){
            change(move,teachplayTree,teachplan);
        }else{
            List<TeachplanDto> teachplans = new ArrayList<>();
            for (int i = 0; i < teachplayTree.size(); i++) {
                if(teachplayTree.get(i).getId().equals(teachplan.getParentid())){
                    teachplans = teachplayTree.get(i).getTeachPlanTreeNodes();
                }
            }
            change(move,teachplans,teachplan);
        }

    }

    @Transactional
    @Override
    public TeachplanMedia associationMedia(BindTeachplanMediaDto bindTeachplanMediaDto) {
//        只允许第二级教学计划绑定媒资文件
        Teachplan teachplan = teachplanMapper.selectById(bindTeachplanMediaDto.getTeachplanId());
        if (teachplan == null){
            OnlineLearnException.cast("没有查询到课程计划!");
        }
        if(teachplan.getGrade() != 2){
            OnlineLearnException.cast("只允许第二级教学计划绑定媒资文件");
        }
//        先删除,把当前课程计划id对应的媒资关联表删除
        teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getTeachplanId,bindTeachplanMediaDto.getTeachplanId()));
//        后插入
        TeachplanMedia teachplanMedia = new TeachplanMedia();
        teachplanMedia.setMediaId(bindTeachplanMediaDto.getMediaId());
        teachplanMedia.setTeachplanId(bindTeachplanMediaDto.getTeachplanId());
        teachplanMedia.setMediaFilename(bindTeachplanMediaDto.getFileName());
        teachplanMedia.setCourseId(teachplan.getCourseId());
        teachplanMedia.setCreateDate(LocalDateTime.now());
        teachplanMediaMapper.insert(teachplanMedia);
        return teachplanMedia;
    }

    @Override
    public RestResponse deleteMedia(String teachPlanId, String mediaId) {
        LambdaQueryWrapper<TeachplanMedia> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TeachplanMedia::getTeachplanId, teachPlanId);
        lambdaQueryWrapper.eq(TeachplanMedia::getMediaId,mediaId);
        int i = teachplanMediaMapper.delete(lambdaQueryWrapper);
        if(i != 1){
            log.error("删除课程计划媒资绑定失败!课程计划id:{},媒资id:{}",teachPlanId,mediaId);
            RestResponse.validfail("删除媒资绑定失败!");
        }
        return new RestResponse(200,"删除媒资绑定成功!");
    }

    private void change(String move,List<TeachplanDto> teachplans,Teachplan teachplan){
        if(MOVEUP.equals(move)){
            for (int i = 0; i < teachplans.size(); i++) {
                if(teachplans.get(i).getId().equals(teachplan.getId())){
                    if(i != 0){
                        Integer orderby = teachplan.getOrderby();
                        teachplan.setOrderby(teachplans.get(i -1).getOrderby());
                        teachplanMapper.updateById(teachplan);
                        teachplan = teachplans.get(i - 1);
                        teachplan.setOrderby(orderby);
                        teachplanMapper.updateById(teachplan);
                        return;
                    }
                }
            }
        }else{
            for (int i = 0; i < teachplans.size(); i++) {
                if(teachplans.get(i).getId().equals(teachplan.getId())){
                    if(i != teachplans.size() - 1){
                        Integer orderby = teachplan.getOrderby();
                        teachplan.setOrderby(teachplans.get(i + 1).getOrderby());
                        teachplanMapper.updateById(teachplan);
                        teachplan = teachplans.get(i + 1);
                        teachplan.setOrderby(orderby);
                        teachplanMapper.updateById(teachplan);
                        return;
                    }
                }
            }
        }
    }
}
